package zcatt.ex007.core.jobs;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobFunction;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.ui.progress.IProgressService;

public class JobView extends ViewPart {

	public static final long sleep = 10;
	public static final long duration = 3000;

	Composite comp;
	
	public JobView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {
		comp = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		comp.setLayout(layout);
		
		//#.
		Button btn;
		btn= new Button(comp, SWT.PUSH);
		btn.setText("create a job");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				createJob();
			}
			
		});

		//#.
		btn= new Button(comp, SWT.PUSH);
		btn.setText("show in dialog");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {				
				Job job = Job.create("ex007 showInDialog job", new MyCoreRunnable());
				job.setProperty(IProgressConstants.KEEP_PROPERTY, true);	//zf, 完成后, 在monitor中留存
				job.schedule();	
				
				IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
				progressService.showInDialog(getSite().getShell(), job);
			}
			
		});

		//#.	
		btn= new Button(comp, SWT.PUSH);
		btn.setText("run coreRunnable in progressService");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent evt) {			
				IWorkspace workspace = ResourcesPlugin.getWorkspace();
				IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
				try {
					progressService.run(true, true, new MyRunnableWithProgress());					
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
			
		});

	
		//#.	
		btn= new Button(comp, SWT.PUSH);
		btn.setText("run coreRunnable in progressService UI");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent evt) {			
				IWorkspace workspace = ResourcesPlugin.getWorkspace();
				IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
				try {
					progressService.runInUI(progressService 
							, new MyRunnableWithProgress()
							, workspace.getRoot());					
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
			
		});

	
		btn= new Button(comp, SWT.PUSH);
		btn.setText("run coreRunnable in workspace");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent evt) {				
				IWorkspace workspace = ResourcesPlugin.getWorkspace();
				IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
				try {
					progressService.runInUI(progressService 
							, monitor->{
								try {
									workspace.run(new MyCoreRunnable(), monitor);
								} catch (CoreException e) {
									e.printStackTrace();
								}
							}
							, workspace.getRoot());					
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
			
		});

	
		btn= new Button(comp, SWT.PUSH);
		btn.setText("run coreRunnable in window");
		btn.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent evt) {				
				try {
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(true,
							true, new MyRunnableWithProgress());			//zf, 使用IWorkbenchWindow.run()

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
		});
}
	
	void createJob()
	{
		IJobFunction jobFunc = new IJobFunction() {

			@Override
			public IStatus run(IProgressMonitor monitor) {	//zf, 默认使用的是ProgressManager.JobMonitor
				int ticks = (int) (duration / sleep);
				monitor.beginTask("start ex007 job", ticks);
				
				try {
					for(int i = 0; i< ticks; i++)
					{
						if(monitor.isCanceled())
							return Status.CANCEL_STATUS;

						monitor.subTask("tick #"+i);
						try {
							Thread.sleep(sleep);
						} catch (InterruptedException e) {
							return Status.CANCEL_STATUS;
						}
						monitor.worked(1);
					}					
				}
				finally {
					monitor.done();					
				}

				return Status.OK_STATUS;
			}			
		};
		
		Job job = Job.create("ex007 job", jobFunc);
		job.setProperty(IProgressConstants.KEEP_PROPERTY, true);	//zf, 完成后, 在monitor中留存
		job.schedule();				//zf, 使用progress view
	}

	@Override
	public void setFocus() {
		comp.setFocus();
	}

	public static class MyRunnableWithProgress implements IRunnableWithProgress{

		@Override
		public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
			int ticks = (int) (duration / sleep);
			monitor.beginTask("start ex007 runnableWithProgress", ticks);
			
			try {
				for(int i = 0; i< ticks; i++)
				{
					if(monitor.isCanceled())
						return;

					monitor.subTask("tick #"+i);
					try {
						Thread.sleep(sleep);
					} catch (InterruptedException e) {
						e.printStackTrace();
						return;
					}
					monitor.worked(1);
				}					
			}
			finally {
				monitor.done();					
			}		
		}
		
	}
	
	public static class MyCoreRunnable implements ICoreRunnable{
		@Override
		public void run(IProgressMonitor monitor) throws CoreException {
			int ticks = (int) (duration / sleep);
			monitor.beginTask("start ex007 coreRunnable", ticks);
			
			try {
				for(int i = 0; i< ticks; i++)
				{
					if(monitor.isCanceled())
						return;

					monitor.subTask("tick #"+i);
					try {
						Thread.sleep(sleep);
					} catch (InterruptedException e) {
						e.printStackTrace();
						return;
					}
					monitor.worked(1);
				}					
			}
			finally {
				monitor.done();					
			}			
		}
		
	}
}
